#include <bits/stdc++.h>
using namespace std;
//map有数种创建的方式
map<string, int> m1;                                                                             //第一种,最常用的方式,会创建一个空的map
map<string, int> m2{{"A", 1}, {"B", 2}, {"C", 1}, {"D", 4}};                                     //第二种,会创建一个有初始值的map,初始值就是后面大括号里有的东西
map<string, int> m3{make_pair("A", 1), make_pair("B", 2), make_pair("C", 1), make_pair("D", 4)}; //第三种,用make_pair()创建pair对象来初始化
map<string, int> m4{m3};                                                                         //第四种,这个方式会复制一个map到新的map里
map<string, int> m5{begin(m4), end(m4)};                                                         //第五种,利用迭代器来制定现有map的一个区间来初始化,由于map支持双向迭代器,所以在创建时可以用++begin()这样的写法来指定一个子集
//注释全都在后面
int main()
{
    //insert()部分
    //这个函数有许多个版本
    auto pr1 = make_pair("D", 4); //值得注意的是,这个make_pair()示例会返回一个pair<const char*,int>对象
    auto _pr1 = make_pair("E", 5);
    //而不是pair<string,int>对象
    auto ret_pr1 = m2.insert(pr1); //但是在此处插入时不会出错,因为insert()函数会把不适合的类型隐式转换为容器元素类型
    auto _ret_pr1 = m2.insert(_pr1);
    //insert()函数会返回一个pair<iterator, bool>的对象
    //第一个值指向插入的值,或是阻止插入的值
    //第二个值代表着是否成功插入
    cout << ret_pr1.first->first << ' ' << ret_pr1.first->second << ' ' << boolalpha << ret_pr1.second << endl;
    cout << _ret_pr1.first->first << ' ' << _ret_pr1.first->second << ' ' << boolalpha << _ret_pr1.second << endl;
    //如果不想要insert()的隐式转换,可以在插入时这么干
    auto pr2 = make_pair<string, int>("F", 6); //make_pair()的全写是make_pair<>(),<>内可以填入两个类型,表示生成的pair的两个值的类型
    auto ret_pr2 = m2.insert(pr2);
    cout << ret_pr2.first->first << ' ' << ret_pr2.first->second << ' ' << boolalpha << ret_pr2.second << endl;
    auto ret_pr3 = m2.insert(pair<string, int>{"G", 7}); //这个方式调用了一个具有右值引用参数的insert()版本,实质上是临时创建一个pair对象并插入
    cout << ret_pr3.first->first << ' ' << ret_pr3.first->second << ' ' << boolalpha << ret_pr3.second << endl;
    auto pr4 = make_pair<string, int>("I", 9);
    auto _pr4 = make_pair<string, int>("H", 8);
    auto ret_pr4 = m2.insert(pr4);
    m2.insert(ret_pr4.first, _pr4); //这个用法给了insert()一个提示符,指出了元素可能的插入位置
    //一般来说,这个提示符是一个迭代器,函数会从这个迭代器向后查找,一直到一个合适的位置后将元素插入
    for (auto iter1 = m2.begin(); iter1 != m2.end(); iter1++)
        cout << iter1->first << ' ' << iter1->second << endl; //这个循环会输出map中所有元素,输出的结果不会是I在前而是排好的H在前
    //还可以将外部源中的一部分元素插入map中,这些元素不必来自于另一个map容器,但必须和被插入容器中的元素是同类型.
    map<string, int> tmp_m{{"J", 10}, {"K", 11}, {"L", 12}, {"M", 13}};
    auto iter1 = tmp_m.begin();
    advance(iter1, 3);
    m2.insert(tmp_m.begin(), iter1);
    cout << "-------" << endl;
    for (auto iter1 = m2.begin(); iter1 != m2.end(); iter1++)
        cout << iter1->first << ' ' << iter1->second << endl;
    //count()函数部分
    //这个函数返回对应键的个数
    //返回值可能是0或1
    if (m2.count("E"))
        cout << "E存在" << endl;
    return 0;
}